package kaa.archivator;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.LinkedList;

import static java.nio.file.StandardOpenOption.APPEND;
import static java.nio.file.StandardOpenOption.CREATE;

 class FileMetaDataRW {
    private RandomAccessFile aFile;



     FileMetaDataRW(Path outFile) {
        try {
            setaFile(new RandomAccessFile(outFile.toFile(), "rw"));
        } catch (FileNotFoundException e) {
            System.out.println("No such file");
        }
    }

    public static LinkedList<Path> buildFileList(Path inFolder) throws IOException {
        MyFileVisitor myVisit = new MyFileVisitor();
        Files.walkFileTree(inFolder, myVisit);
        return myVisit.getFlist();
    }

    private boolean isDirectory(Path file) throws IOException {
        return Files.readAttributes(file, BasicFileAttributes.class).isDirectory();
    }

    public void writeToFile(Path myPath) throws IOException {
        LinkedList<Path> flist;
        flist = buildFileList(myPath);
        Path firstFile = flist.removeLast();
        boolean isDir = isDirectory(firstFile);
        FileInfo info = new FileInfo(firstFile, firstFile, isDir);
        byte[] meta;
        meta = isDir ? info.getByteMetaInfo() : info.getByteFullInfo();
        aFile.write(meta);
        while (!flist.isEmpty()) {
            meta = null;
            Path tmp = flist.removeLast();
            isDir = isDirectory(tmp);
            info = new FileInfo(tmp, firstFile, isDir);
            meta = isDir ? info.getByteMetaInfo() : info.getByteFullInfo();
            aFile.write(meta);
        }
    }

    public void readFromFile(Path myPath, String outFile) throws IOException {
        readFromFile(myPath, outFile, false);
    }

    public void readFromFile(Path myPath) throws IOException {
        readFromFile(myPath, "", true);
    }

    private void readFromFile(Path myPath, String outPath, boolean showContents) throws IOException {
        setaFile(new RandomAccessFile(myPath.toFile(), "r"));
        int fsize;
        while (aFile.getFilePointer() != aFile.length()) {
            fsize = aFile.readInt();
            byte[] b = new byte[fsize];
            aFile.read(b);
            FileInfo inf = new FileInfo();
            inf.setMetaInfo(b);
            System.out.println(inf.getFilepath().toString());
            Path tmp = FileSystems.getDefault().getPath(outPath + inf.getFilepath());

            if (inf.getSize() != -1) {
                int fileSize = aFile.readInt();
                if (showContents) {
                    aFile.skipBytes(fileSize);
                } else {
                    Files.createDirectories(tmp.subpath(0, tmp.getNameCount() - 1));
                    byte[] file = new byte[fileSize];
                    aFile.read(file);
                    inf.setFile(file);
                    Files.write(tmp, file, CREATE, APPEND);
                   // System.out.println(new String(inf.getFile()));
                }
            } else if (!showContents) {
                Files.createDirectories(tmp);
            }
        }
    }

     public RandomAccessFile getaFile() {
         return aFile;
     }

     public void setaFile(RandomAccessFile aFile) {
         this.aFile = aFile;
     }
 }
